/**
 * 2024/01/01 - 2024/12/31
 **/
package com.snail.camunda.engin.process.holder;

import com.snail.camunda.engin.process.dto.DoneDTO;
import com.snail.starter.commons.page.PageQO;
import com.snail.starter.commons.page.PageVO;
import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.history.HistoricTaskInstanceQuery;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: (zg)
 * @Date: 2024/12/16 11:42
 * @Version: 1.0.0
 */
@Component
public class HistoryHolder {

    @Resource
    HistoryService historyService;

    public HistoricTaskInstanceQuery createHistoricTaskInstanceQuery(DoneDTO done) {
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
        if (null != done && null != done.getAssignee()) {
            historicTaskInstanceQuery.taskAssignee(done.getAssignee());
        }
        return historicTaskInstanceQuery;
    }

    public long count(HistoricTaskInstanceQuery historicTaskInstanceQuery) {
        return historicTaskInstanceQuery.count();
    }

    public PageVO<HistoricTaskInstance> page(PageQO<DoneDTO> page) {
        return page(page, historicTaskInstance -> historicTaskInstance);
    }

    public <T> PageVO<T> page(PageQO<DoneDTO> page, Function<HistoricTaskInstance, T> function) {
        HistoricTaskInstanceQuery historicTaskInstanceQuery = createHistoricTaskInstanceQuery(page.getQuery());
        long count = count(historicTaskInstanceQuery);
        if (0L == count) {
            return PageVO.of(page.getPageNum() - 1, page.getPageSize(), 0L, new ArrayList<>());
        }
        List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.listPage(page.getPageNum(), page.getPageSize());
        if (null == historicTaskInstances || historicTaskInstances.isEmpty()) {
            return PageVO.of(page.getPageNum(), page.getPageSize(), count, new ArrayList<>());
        }
        return PageVO.of(page.getPageNum(), page.getPageSize(), count, historicTaskInstances.stream().map(function).collect(Collectors.toList()));
    }

    public List<HistoricTaskInstance> history(String processInstanceId) {
        return historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId).finished()
                .orderByHistoricTaskInstanceEndTime().asc()
                .list();
    }

}